home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt3sp3.arc / PIBVT52.PAS < prev    next >
Pascal/Delphi Source File  |  1985-10-04  |  31KB  |  722 lines

  1. (*----------------------------------------------------------------------*)
  2. (*             VT52.PAS --- Emulate Dec VT52 for PIBTERM                *)
  3. (*----------------------------------------------------------------------*)
  4. (*                                                                      *)
  5. (*  Author:  Philip R. Burns                                            *)
  6. (*  Date:    October, 1984      (Version 1.0)                           *)
  7. (*           June, 1985         (Version 2.0)                           *)
  8. (*           July, 1985         (Version 2.1)                           *)
  9. (*                                                                      *)
  10. (*  Systems: For MS-DOS on IBM PCs and close compatibles only.          *)
  11. (*           Note:  I have checked these on Zenith 151s under           *)
  12. (*                  MSDOS 2.1 and IBM PCs under PCDOS 2.0.              *)
  13. (*                                                                      *)
  14. (*  History: Original with me.                                          *)
  15. (*                                                                      *)
  16. (*           Greg Ryan provided the original form of the code to        *)
  17. (*           execute EXEC PC BBS commands.                              *)
  18. (*                                                                      *)
  19. (*           Suggestions for improvements or corrections are welcome.   *)
  20. (*           Please leave messages on Gene Plantz's BBS (312) 882 4145  *)
  21. (*           or Ron Fox's BBS (312) 940 6496.                           *)
  22. (*                                                                      *)
  23. (*           IF you use this code in your own programs, please be nice  *)
  24. (*           and give proper credit.                                    *)
  25. (*                                                                      *)
  26. (*----------------------------------------------------------------------*)
  27. (*                                                                      *)
  28. (*  Routines:                                                           *)
  29. (*                                                                      *)
  30. (*      Scroll                                                          *)
  31. (*      Get_Async_Integer                                               *)
  32. (*      Do_CompuServe_B_Transfer                                        *)
  33. (*      Emulate_VT52                                                    *)
  34. (*      Convert_VT52_Kbd                                                *)
  35. (*      Convert_VT52_Comm                                               *)
  36. (*      Exec_PC_Commands                                                *)
  37. (*                                                                      *)
  38. (*----------------------------------------------------------------------*)
  39. (*                                                                      *)
  40. (*  Remarks:                                                            *)
  41. (*                                                                      *)
  42. (*     The VT52 keypad is mapped onto the function keys as follows:     *)
  43. (*                                                                      *)
  44. (*        The left half of the keypad --> function keys F1 through F10. *)
  45. (*        The right half of the keypad --> function keys Shift F1 thru  *)
  46. (*        Shift F10.                                                    *)
  47. (*                                                                      *)
  48. (*     For convenience, the arrow keys can also be used to generate     *)
  49. (*     the same codes as the arrows from the function keys.             *)
  50. (*                                                                      *)
  51. (*     For those VT52 keypad keys which are double-sized, two adjacent  *)
  52. (*     function keys will send the same codes.                          *)
  53. (*                                                                      *)
  54. (*     Note that the function keys are always in keypad application     *)
  55. (*     mode.  Numeric codes can be sent using the regular PC keypad.    *)
  56. (*                                                                      *)
  57. (*----------------------------------------------------------------------*)
  58.  
  59.  
  60. (*----------------------------------------------------------------------*)
  61. (*                Emulate_VT52 -- Controls VT52 emulation               *)
  62. (*----------------------------------------------------------------------*)
  63.  
  64. OVERLAY PROCEDURE Emulate_VT52;
  65.  
  66. (*----------------------------------------------------------------------*)
  67. (*                                                                      *)
  68. (*    Routine:  Emulate_VT52                                            *)
  69. (*                                                                      *)
  70. (*    Purpose:  Controls VT52 terminal emulation                        *)
  71. (*                                                                      *)
  72. (*    Calling Sequence:                                                 *)
  73. (*                                                                      *)
  74. (*       Emulate_VT52;           No arguments                           *)
  75. (*                                                                      *)
  76. (*    Calls:                                                            *)
  77. (*                                                                      *)
  78. (*       Convert_VT52_kbd            Maps PC input to VT52 codes        *)
  79. (*       Convert_VT52_Comm           Maps received VT52 codes to PC     *)
  80. (*                                                                      *)
  81. (*    Called by:  PIBTERM                                               *)
  82. (*                                                                      *)
  83. (*    Remarks:                                                          *)
  84. (*                                                                      *)
  85. (*       (1)  The graphics characters produced in graphics mode are     *)
  86. (*            VT100 graphics characters.  This is what many VT100s      *)
  87. (*            and compatibles produce in VT52 mode.                     *)
  88. (*                                                                      *)
  89. (*       (2)  Tab positions on the VT52 are located in fixed positions. *)
  90. (*            Those are the positions used here.  Some VT52-like        *)
  91. (*            terminals allow user-settable tabs.  Those are not        *)
  92. (*            implemented here.                                         *)
  93. (*                                                                      *)
  94. (*----------------------------------------------------------------------*)
  95.  
  96. CONST
  97.    ON   = TRUE                       (* Convenient synonym for switches *);
  98.    OFF  = FALSE                      (* Likewise                        *);
  99.  
  100. VAR
  101.    Comm_Ch            : CHAR         (* Character read from comm port   *);
  102.    Kbd_Ch             : CHAR         (* Character read from keyboard    *);
  103.    VT52_Graphics_Mode : BOOLEAN      (* TRUE if VT52 graphics mode on   *);
  104.    VT52_KeyPad        : BOOLEAN      (* TRUE if alternate keypad in use *);
  105.    Done               : BOOLEAN      (* TRUE to stop VT52 emulation     *);
  106.    B                  : BOOLEAN      (* General purpose flag            *);
  107.    Graph_Ch           : BYTE         (* Graphics character              *);
  108.    Itab               : BYTE         (* Tab stop                        *);
  109.    Tabcol             : BYTE         (* Tab column                      *);
  110.    Curcol             : BYTE         (* Current column in display       *);
  111.    Auto_Print_Mode    : BOOLEAN      (* IF auto print mode in effect    *);
  112.    Printer_Ctrl_Mode  : BOOLEAN      (* IF printer controller mode on   *);
  113.    Print_Line         : STRING[80]   (* Line to print if print mode on  *);
  114.  
  115. CONST
  116.    Graphics_Chars: ARRAY[ 95 .. 126 ] Of BYTE
  117.                    = (  32,   4, 177,   9,  12,  13,  10, 248, 241,
  118.                         10,  10, 217, 191, 218, 192, 197, 196, 196,
  119.                        196, 196,  95, 195, 180, 193, 194, 179, 243,
  120.                        242, 227, 168, 156, 250 );
  121.  
  122.    Number_VT52_Tabs = 16;
  123.  
  124.    VT52_Tabs:  ARRAY[ 1 .. Number_VT52_Tabs ] Of BYTE
  125.                = (  9, 17, 25, 33, 41, 49, 57, 65, 73, 74, 75, 76, 77,
  126.                    78, 79, 80 );
  127.  
  128. (*----------------------------------------------------------------------*)
  129. (*               Scroll --- Scroll section of screen                    *)
  130. (*----------------------------------------------------------------------*)
  131.  
  132. PROCEDURE Scroll ( Y1, Y2, X1, X2, Nlines : INTEGER );
  133.  
  134. (*----------------------------------------------------------------------*)
  135. (*                                                                      *)
  136. (*   Procedure: Scroll                                                  *)
  137. (*                                                                      *)
  138. (*   Purpose:   Scrolls portion of screen.                              *)
  139. (*                                                                      *)
  140. (*   Calling sequence:                                                  *)
  141. (*                                                                      *)
  142. (*      Scroll( Y1, Y2, X1, X2, Nlines : INTEGER );                     *)
  143. (*                                                                      *)
  144. (*          (X1,Y1); (X2,Y2) --- corners of region to scroll            *)
  145. (*          Nlines           --- number of lines to scroll              *)
  146. (*                                                                      *)
  147. (*   Calls:  INTR                                                       *)
  148. (*                                                                      *)
  149. (*   Remarks:                                                           *)
  150. (*                                                                      *)
  151. (*      The indicated portion of the screen is scrolled up or down.     *)
  152. (*      If Nlines > 0, then the screen is scrolled up.  If Nlines < 0,  *)
  153. (*      the screen is scrolled down.  Setting Nlines to zero blanks     *)
  154. (*      the entire region.                                              *)
  155. (*                                                                      *)
  156. (*                                                                      *)
  157. (*----------------------------------------------------------------------*)
  158.  
  159. VAR
  160.   Reg: Regpack;
  161.  
  162. BEGIN (* Scroll *)
  163.  
  164.    Reg.Cl := Y1;
  165.    Reg.Ch := X1;
  166.  
  167.    Reg.Dl := Y2;
  168.    Reg.Dh := X2;
  169.  
  170.    Reg.Bx := 0;
  171.  
  172.    IF Nlines >= 0 THEN
  173.       Reg.Ax := $0600 OR Nlines
  174.    ELSE
  175.       Reg.Ax := $0700 OR ABS( Nlines );
  176.  
  177.   INTR( $10 , Reg );
  178.  
  179. END  (* Scroll *);
  180.  
  181. (*----------------------------------------------------------------------*)
  182. (*     Get_Async_Integer   --- get integer in biased VT52 form          *)
  183. (*----------------------------------------------------------------------*)
  184.  
  185. PROCEDURE Get_Async_Integer( VAR Integr: INTEGER );
  186.  
  187. (*----------------------------------------------------------------------*)
  188. (*                                                                      *)
  189. (*   Procedure: Get_Async_Integer                                       *)
  190. (*                                                                      *)
  191. (*   Purpose:  Gets integer in biased VT52 form from COM port           *)
  192. (*                                                                      *)
  193. (*   Calling sequence:                                                  *)
  194. (*                                                                      *)
  195. (*      Get_Async_Integer( Var Integr: INTEGER );                       *)
  196. (*                                                                      *)
  197. (*         Integr: Returned integer value                               *)
  198. (*                                                                      *)
  199. (*   Calls:  None                                                       *)
  200. (*                                                                      *)
  201. (*   Called by:   Convert_VT52_Kbd                                      *)
  202. (*                Convert_VT52_Comm                                     *)
  203. (*                                                                      *)
  204. (*   Remarks:                                                           *)
  205. (*                                                                      *)
  206. (*      The screen positions on the VT52 are expressed in excess 31     *)
  207. (*      notation.  That is, the value 31 is added to each row and       *)
  208. (*      column value.                                                   *)
  209. (*                                                                      *)
  210. (*----------------------------------------------------------------------*)
  211.  
  212. VAR
  213.    C  : INTEGER;
  214.  
  215. BEGIN (* Get_Async_Integer *)
  216.  
  217.    Async_Receive_With_TimeOut( 1 , C );
  218.  
  219.    IF C = TimeOut THEN
  220.       Integr := 0
  221.    ELSE
  222.       Integr := C - 31;
  223.  
  224. END   (* Get_Async_Integer *);
  225.  
  226. (*----------------------------------------------------------------------*)
  227. (*           Exec_PC_Commands  --- Process EXEC PC BBS commands         *)
  228. (*----------------------------------------------------------------------*)
  229.  
  230. PROCEDURE Exec_PC_Commands;
  231.  
  232. (*----------------------------------------------------------------------*)
  233. (*                                                                      *)
  234. (*     Procedure:  Exec_PC_Commands                                     *)
  235. (*                                                                      *)
  236. (*     Purpose:    Process Exec PC BBS special escape code commands     *)
  237. (*                                                                      *)
  238. (*     Calling Sequence:                                                *)
  239. (*                                                                      *)
  240. (*        Exec_PC_Commands;                                             *)
  241. (*                                                                      *)
  242. (*     Calls:                                                           *)
  243. (*                                                                      *)
  244. (*        Async_Send                                                    *)
  245. (*        Async_Receive                                                 *)
  246. (*        PibDownLoad                                                   *)
  247. (*                                                                      *)
  248. (*----------------------------------------------------------------------*)
  249.  
  250. VAR
  251.    X:      INTEGER;
  252.    Y:      INTEGER;
  253.    Ch:     CHAR;
  254.    C:      INTEGER;
  255.  
  256. BEGIN (* Exec_PC_Commands *)
  257.  
  258.                                    (* Get next character after Exec PC flag *)
  259.  
  260.    Async_Receive_With_TimeOut( 1 , C );
  261.  
  262.    IF C <> TimeOut THEN
  263.       Ch := CHR( C )
  264.    ELSE
  265.       Ch := CHR( 0 );
  266.                                    (* Handle it *)
  267.  
  268.    CASE Ch OF
  269.  
  270.       'D' : BEGIN (* Auto-Download *)
  271.  
  272.                FileName := '';
  273.  
  274.                WRITE('Autodownloading         ');
  275.  
  276.                REPEAT
  277.  
  278.                   Async_Receive_With_TimeOut( 1 , C );
  279.  
  280.                   IF C <> TimeOut THEN
  281.                      Ch := CHR( C )
  282.                   ELSE
  283.                      Ch := CHR( 0 );
  284.  
  285.                   IF NOT ( ORD( Ch ) IN [ACK,CAN] ) THEN
  286.                      BEGIN
  287.                         Async_Send( Ch );       (* echo 1 char at a time *)
  288.                         FileName := FileName + Ch;
  289.                         WRITE( Ch );
  290.                      END;
  291.  
  292.                UNTIL ORD(Ch) IN [ACK,CAN];
  293.  
  294.                IF ORD( Ch ) = ACK THEN
  295.                      BEGIN  (* Filename echoed correctly *)
  296.  
  297.                         FOR X := 0 TO 18 DO
  298.                            WRITELN;
  299.  
  300.                         IF POS( '=X' , FileName ) <> 0 THEN
  301.                            DELETE( FileName , POS( '=X' , FileName ) , 2 );
  302.  
  303.                         FileName := TRIM( FileName );
  304.  
  305.                         PibDownload( Xmodem_Chk );
  306.  
  307.                      END;
  308.  
  309.             END  (* Auto_DownLoad *);
  310.  
  311.       '2' : BEGIN  (* Draw a Box at corners (Oldx,Oldy) and (NewX,NewY) *)
  312.  
  313.                GoToXY( OldX , OldY );
  314.  
  315.                WRITE( CHR(218) );      (* upper left corner *)
  316.  
  317.                FOR X := ( OldX + 1 ) TO ( NewX - 1 ) DO
  318.                   WRITE( CHR(196) );    (* horizontal line segment *)
  319.  
  320.                WRITE( CHR(191) );       (* upper right corner *)
  321.  
  322.                FOR Y := ( OldY + 1 ) TO ( NewY - 1 ) DO
  323.                   BEGIN
  324.                      GoToXY( OldX , Y );
  325.                      WRITE( CHR(179) );  (* vertical line segment *)
  326.                      GoToXY( NewX , y );
  327.                      WRITE( CHR(179) );
  328.                   END;
  329.  
  330.                GoToXY( OldX , NewY );
  331.                WRITE( CHR(192) );      (* lower left corner *)
  332.  
  333.                FOR X := ( OldX + 1 ) TO ( NewX - 1 ) DO
  334.                   WRITE(CHR(196));
  335.  
  336.                WRITE(CHR(217));      (* lower right corner *)
  337.  
  338.             END;
  339.  
  340.       ELSE;
  341.  
  342.    END (* CASE *);
  343.  
  344. END   (* Exec_PC_Commands *);
  345.  
  346. (*----------------------------------------------------------------------*)
  347. (*    Convert_VT52_Comm --- Process incoming VT52 escape sequences      *)
  348. (*----------------------------------------------------------------------*)
  349.  
  350. PROCEDURE Convert_VT52_Comm;
  351.  
  352. (*----------------------------------------------------------------------*)
  353. (*                                                                      *)
  354. (*     Routine:  Convert_VT52_Comm                                      *)
  355. (*                                                                      *)
  356. (*     Purpose:  Executes incoming VT52 escape sequences                *)
  357. (*                                                                      *)
  358. (*                                                                      *)
  359. (*     Calling Sequence:                                                *)
  360. (*                                                                      *)
  361. (*        Convert_VT52_Comm;             -- no parameters --            *)
  362. (*                                                                      *)
  363. (*     Calls:  Exec_PC_Commands                                         *)
  364. (*             Scroll                                                   *)
  365. (*                                                                      *)
  366. (*     Called by:  Emulate_VT52                                         *)
  367. (*                                                                      *)
  368. (*     Remarks:                                                         *)
  369. (*                                                                      *)
  370. (*        This routine assumes that a CHR(27) (Escape) was just read.   *)
  371. (*        The following character is assumed to be a VT52 code.         *)
  372. (*                                                                      *)
  373. (*----------------------------------------------------------------------*)
  374.  
  375. VAR
  376.    Ch:  CHAR;
  377.    X:   INTEGER;
  378.    Y:   INTEGER;
  379.    Y2:  INTEGER;
  380.    B:   BOOLEAN;
  381.    C:   INTEGER;
  382.  
  383. BEGIN (* Convert_VT52_Comm *)
  384.  
  385.    Async_Receive_With_TimeOut( 1 , C );
  386.  
  387.    IF C <> TimeOut THEN
  388.       Ch := CHR( C )
  389.    ELSE
  390.       Ch := CHR( 0 );
  391.  
  392.    Ch     := TrTab[ Ch ];
  393.  
  394.    CASE  Ch  OF
  395.  
  396.       'A':  BEGIN (* Move cursor up *)
  397.                GoToXY( Wherex, Max( WhereY - 1 , 1 ) );
  398.             END;
  399.  
  400.       'B':  BEGIN (* Move cursor down *)
  401.                GoToXY( Wherex, Min( WhereY + 1 , 25 ) );
  402.             END;
  403.  
  404.       'C':  BEGIN (* Move cursor left *)
  405.                GoToXY( Max( Wherex - 1 , 1 ), WhereY );
  406.             END;
  407.  
  408.       'D':  BEGIN (* Move cursor right *)
  409.                GoToXY( Min( WhereX + 1 , 80 ), WhereY );
  410.             END;
  411.  
  412.       'F':  VT52_Graphics_Mode := TRUE;
  413.  
  414.       'G':  VT52_Graphics_Mode := FALSE;
  415.  
  416.       'H':  GoToXY( 1 , 1 );
  417.  
  418.       'I':  BEGIN
  419.                X := WhereX;
  420.                Y := WhereY - 1;
  421.                IF y > 0 THEN
  422.                   GoToXY( X , Y )
  423.                ELSE
  424.                   Scroll( 1, 25, 1, 80, -1 );
  425.             END;
  426.  
  427.       'J':  BEGIN (* Clear to END of Screen *)
  428.  
  429.                X := WhereX;
  430.                Y := WhereY;
  431.  
  432.                ClrEol;
  433.  
  434.                FOR Y2 := ( Y + 1 ) To 25 DO
  435.                   BEGIN
  436.                      GoToXY( 1 , Y2 );
  437.                      ClrEol;
  438.                   END;
  439.  
  440.               GoToXY( X , Y );
  441.  
  442.             END;
  443.  
  444.       'K':  ClrEol (* Clear to END of Line *);
  445.  
  446.       'L':  ClrScr;
  447.  
  448.       'O':  IF Mahoney_On THEN Exec_PC_Commands;
  449.  
  450.       'W':  Printer_Ctrl_Mode := ON;
  451.  
  452.       'X':  Printer_Ctrl_Mode := OFF;
  453.  
  454.       'Y':  BEGIN  (* Move to screen position *)
  455.  
  456.                OldX   := NewX;
  457.                OldY   := NewY;
  458.  
  459.                Get_Async_Integer( NewY );
  460.                Get_Async_Integer( NewX );
  461.  
  462.                NewY := MAX( 1 , MIN( NewY , 25 ) );
  463.                NewX := MAX( 1 , MIN( NewX , 80 ) );
  464.  
  465.                GoToXY( NewX, NewY );
  466.  
  467.             END;
  468.  
  469.       'Z':  Async_Send_String( Chr(27) + '/Z' )    (* Identify *);
  470.  
  471.       '=':  VT52_Keypad := ON    (* Enter keypad mode *);
  472.  
  473.       '>':  VT52_Keypad := OFF   (* Exit keypad mode *);
  474.  
  475.       ']':  Print_Screen;
  476.  
  477.       '-':  Auto_Print_Mode := OFF;
  478.  
  479.       '^':  Auto_Print_Mode := ON;
  480.  
  481.                                    (* Indicate EXEC PC AutoDownload possible *)
  482.  
  483.       ^Q :  IF Mahoney_On THEN Async_Send_String( 'EXECPC2' );
  484.  
  485.       ELSE
  486.             ;
  487.  
  488.    END (* Case CH *);
  489.  
  490.  
  491. END   (* Convert_VT52_Comm *);
  492.  
  493. (*----------------------------------------------------------------------*)
  494. (*            Convert_VT52_Kbd -- Controls VT52 keyboard emulation      *)
  495. (*----------------------------------------------------------------------*)
  496.  
  497. PROCEDURE Convert_VT52_Kbd( VAR Done : BOOLEAN );
  498.  
  499. (*----------------------------------------------------------------------*)
  500. (*                                                                      *)
  501. (*     Routine:  Convert_VT52_Kbd                                       *)
  502. (*                                                                      *)
  503. (*     Purpose:  Convert PC keyboard codes to VT52 escape sequences     *)
  504. (*                                                                      *)
  505. (*     Calling Sequence:                                                *)
  506. (*                                                                      *)
  507. (*        Convert_VT52_Kbd( Var Done: BOOLEAN );                        *)
  508. (*                                                                      *)
  509. (*           Done --- set TRUE if ALtX encountered                      *)
  510. (*                                                                      *)
  511. (*     Calls:  None                                                     *)
  512. (*                                                                      *)
  513. (*     Called by:  Emulate_VT52                                         *)
  514. (*                                                                      *)
  515. (*     Remarks:                                                         *)
  516. (*                                                                      *)
  517. (*        A more efficient method of writing this routine would be to   *)
  518. (*        use a simple replace via table lookup of the PC code by the   *)
  519. (*        VT52 code.                                                    *)
  520. (*                                                                      *)
  521. (*----------------------------------------------------------------------*)
  522.  
  523. CONST
  524.    Esc_Ch   = ^[;
  525.    Esc_Ch_Q = ^['?';
  526.  
  527. VAR
  528.    X:   INTEGER;
  529.    Y:   INTEGER;
  530.    Ch:  Char;
  531.  
  532. BEGIN (* Convert_VT52_Kbd *)
  533.  
  534.    READ( Kbd , Ch );
  535.  
  536.    CASE  ORD( Ch )  OF
  537.  
  538.                    (* Arrows *)
  539.  
  540.       72:  Async_Send_String( Esc_Ch + 'A' );    (* Up Arrow     *)
  541.       80:  Async_Send_String( Esc_Ch + 'B' );    (* Down Arrow   *)
  542.       77:  Async_Send_String( Esc_Ch + 'C' );    (* Right Arrow  *)
  543.       75:  Async_Send_String( Esc_Ch + 'D' );    (* Left Arrow   *)
  544.  
  545.                    (* VT52_Keypad *)
  546.  
  547.       59:  Async_Send_String( Esc_Ch + 'P' );    (* Blue         *)
  548.       60:  Async_Send_String( Esc_Ch + 'Q' );    (* Red          *)
  549.       84:  Async_Send_String( Esc_Ch + 'R' );    (* Gray         *)
  550.       85:  Async_Send_String( Esc_Ch + 'A' );    (* Up Arrow     *)
  551.  
  552.       61:  Async_Send_String( Esc_Ch_Q + 'w' );  (* 7            *)
  553.       62:  Async_Send_String( Esc_Ch_Q + 'x' );  (* 8            *)
  554.       86:  Async_Send_String( Esc_Ch_Q + 'y' );  (* 9            *)
  555.       87:  Async_Send_String( Esc_Ch_Q + 'B' );  (* Down Arrow   *)
  556.  
  557.       63:  Async_Send_String( Esc_Ch_Q + 't' );  (* 4            *)
  558.       64:  Async_Send_String( Esc_Ch_Q + 'u' );  (* 5            *)
  559.       88:  Async_Send_String( Esc_Ch_Q + 'v' );  (* 6            *)
  560.       89:  Async_Send_String( Esc_Ch_Q + 'C' );  (* Right Arrow  *)
  561.  
  562.       65:  Async_Send_String( Esc_Ch_Q + 'q' );  (* 1            *)
  563.       66:  Async_Send_String( Esc_Ch_Q + 'r' );  (* 2            *)
  564.       90:  Async_Send_String( Esc_Ch_Q + 's' );  (* 3            *)
  565.       91:  Async_Send_String( Esc_Ch_Q + 'D' );  (* Left Arrow   *)
  566.  
  567.       67:  Async_Send_String( Esc_Ch_Q + 'p' );  (* 0            *)
  568.       68:  Async_Send_String( Esc_Ch_Q + 'p' );  (* 0            *)
  569.       92:  Async_Send_String( Esc_Ch_Q + 'n' );  (* Period       *)
  570.       93:  Async_Send_String( Esc_Ch_Q + 'M' );  (* Enter        *)
  571.  
  572.                    (* Cursor Movement *)
  573.  
  574.       79:  Async_Send_String( Esc_Ch + 'K' );    (* Erase to EOL *)
  575.      117:  Async_Send_String( Esc_Ch + 'J' );    (* Erase to EOS *)
  576.  
  577.       71:  Async_Send_String( Esc_Ch + 'H' );    (* Home cursor  *)
  578.  
  579.       ELSE
  580.            BEGIN
  581.               Process_Command( Ch, TRUE, PibTerm_Command );
  582.               IF PibTerm_Command <> Null_Command THEN
  583.                  Execute_Command( PibTerm_Command, Done, FALSE );
  584.            END;
  585.  
  586.    END (* Case CH *);
  587.  
  588. END   (* Convert_VT52_Kbd *);
  589.  
  590. (*----------------------------------------------------------------------*)
  591.  
  592. BEGIN (* Emulate_VT52 *)
  593.                                    (* Indicate VT52 being simulated *)
  594.    Save_Screen( Saved_Screen );
  595.    Draw_Menu_Frame( 10, 10, 55, 15, Menu_Frame_Color,
  596.                     Menu_Text_Color, '' );
  597.  
  598.    WRITELN('Beginning VT52 Terminal Emulation');
  599.    DELAY( One_Second_Delay );
  600.  
  601.    Restore_Screen( Saved_Screen );
  602.    Reset_Global_Colors;
  603.                                    (* Initialize terminal state     *)
  604.    Done               := FALSE;
  605.    VT52_Keypad        := OFF;
  606.    VT52_Graphics_Mode := OFF;
  607.    Auto_Print_Mode    := OFF;
  608.    Printer_Ctrl_Mode  := OFF;
  609.    Auto_Wrap_Mode     := ON;
  610.    NewX               := WhereX;
  611.    NewY               := WhereY;
  612.  
  613.                                    (* Loop over input until done *)
  614.    While ( NOT Done ) DO
  615.       BEGIN
  616.  
  617.          IF KeyPressed THEN
  618.             BEGIN (* KeyPressed *)
  619.  
  620.                READ( Kbd , Comm_Ch );
  621.  
  622.                CASE ORD( Comm_Ch ) OF
  623.  
  624.                   ESC:  IF KeyPressed THEN
  625.                            Convert_VT52_Kbd( Done )
  626.                         ELSE
  627.                            BEGIN
  628.                               IF Local_Echo THEN WRITE( Comm_Ch );
  629.                               Async_Send( Comm_Ch );
  630.                            END;
  631.  
  632.  
  633.                   BS:   BEGIN
  634.                            Comm_Ch := BS_Char;
  635.                            IF Local_Echo THEN Write( Comm_Ch );
  636.                            Async_Send( Comm_Ch );
  637.                         END;
  638.  
  639.                   DEL:  BEGIN
  640.                            Comm_Ch := Ctrl_BS_Char;
  641.                            IF Local_Echo THEN Write( Comm_Ch );
  642.                            Async_Send( Comm_Ch );
  643.                         END;
  644.  
  645.                   ELSE
  646.                         BEGIN
  647.                            IF Local_Echo THEN Write( Comm_Ch );
  648.                            Async_Send( Comm_Ch );
  649.                         END;
  650.  
  651.                END (* CASE ORD( Comm_Ch ) *);
  652.  
  653.             END (* KeyPressed *);
  654.  
  655.          IF ( Script_File_Mode AND ( NOT ( Done OR Really_Wait_String ) ) ) THEN
  656.             BEGIN
  657.                Get_Script_Command( PibTerm_Command );
  658.                Execute_Command   ( PibTerm_Command , Done , TRUE );
  659.             END;
  660.  
  661.          IF Async_Receive( Comm_Ch ) THEN
  662.  
  663.             BEGIN  (* Comm_Ch found *)
  664.  
  665.                Async_Buffer_Full;
  666.  
  667.                Comm_Ch := TrTab[ Comm_Ch ];
  668.  
  669.                CASE ORD( Comm_Ch ) OF
  670.  
  671.                   ESC:  Convert_VT52_Comm;
  672.  
  673.                   LF,
  674.                   FF,
  675.                   VT:   BEGIN (* go down one line *)
  676.                            Display_Character( CHR( LF ) );
  677.                            IF Auto_Print_Mode THEN
  678.                               BEGIN
  679.                                  Get_Screen_Text_Line( Print_Line, WhereY - 1,
  680.                                                        1 );
  681.                                  WRITELN( Lst , Print_Line );
  682.                               END;
  683.                         END   (* go down one line *);
  684.  
  685.                   HT:   BEGIN (* Convert tabs to sequence of blanks *)
  686.                            Curcol := WhereX;
  687.                            Itab   := 1;
  688.                            WHILE( Curcol > VT52_Tabs[Itab] ) DO
  689.                               Itab := Itab + 1;
  690.                            Tabcol := VT52_Tabs[Itab];
  691.                            FOR Itab := Curcol To ( Tabcol - 1 ) DO
  692.                               WRITE(' ');
  693.                         END   (* Tabs *);
  694.  
  695.                                    (* CompuServe B protocol request *)
  696.  
  697.                   ENQ:  IF CompuServe_B_On THEN
  698.                            B := Do_CompuServe_B_Transfer
  699.                         ELSE
  700.                            Display_Character( Comm_Ch );
  701.  
  702.                   ELSE
  703.                      IF NOT VT52_Graphics_Mode THEN
  704.                         Display_Character( Comm_Ch )
  705.                      ELSE
  706.                         BEGIN (* Graphics Mode *)
  707.                            IF ORD( Comm_Ch ) IN [ 95 .. 126 ] THEN
  708.                               BEGIN
  709.                                  Graph_Ch := Graphics_Chars[ ORD( Comm_Ch ) ];
  710.                                  Display_Character( CHR( Graph_Ch ) );
  711.                               END
  712.                            ELSE
  713.                               Display_Character( Comm_Ch );
  714.                         END   (* Graphics Mode *);
  715.  
  716.                END (* CASE ORD( Comm_Ch ) *);
  717.  
  718.             END (* Comm_Ch found *);
  719.  
  720.       END  (* NOT Done *);
  721.  
  722. END   (* Emulate_VT52 *);